<template>
  <section class="wh-full">
    <header class="flex-b plr-16px h-64px bg-#fff rd-4px">
      <a-form ref="searchRormRef" :model="searchFormState" name="searchForm" layout="inline" autocomplete="off" @finish="onFinishSearch">
        <a-form-item label="用户名" name="username">
          <a-input v-model:value="searchFormState.username"> </a-input>
        </a-form-item>
        <a-form-item label="手机号" name="phone">
          <a-input v-model:value="searchFormState.phone"> </a-input>
        </a-form-item>
        <a-form-item>
          <a-space>
            <a-button :disabled="disabledSeachBtn" type="primary" html-type="submit">搜索</a-button>
            <a-button key="reset" @click="resetSearchForm">重置</a-button>
          </a-space>
        </a-form-item>
      </a-form>
    </header>
    <section class="main-box bg-#fff rd-4px plr-16px">
      <div class="h-52px flex-b">
        <div class="text-18px font-bold">用户列表</div>
        <div>
          <a-space>
            <a-button type="primary" size="middle" @click.stop="showModal('新增用户', CURDTYPE.新增)">新增用户</a-button>
          </a-space>
        </div>
      </div>
      <div class="main-content" ref="mainContentRef">
        <a-table
          :columns="columns"
          :row-key="(record) => record.id"
          :loading="tableLoading"
          :data-source="tableData"
          :pagination="pageSet"
          :scroll="{ x: 1500, y: tableHeight }"
          :locale="{ filterConfirm: '确定', filterReset: '重置', emptyText: '暂无数据' }"
          @change="handleTableChange"
          bordered
        >
          <template #bodyCell="{ index, column, record }">
            <template v-if="column.key === 'index'">
              <div>{{ index + 1 }}</div>
            </template>
            <template v-if="column.key === 'gender'">
              <div>{{ UserGender[record.gender] }}</div>
            </template>
            <template v-if="column.key === 'operation'">
              <a-space>
                <a-button size="small" @click.stop="showModal('查看用户信息', CURDTYPE.查看, record as TableRowFeilds)">查看</a-button>
                <a-button type="primary" size="small" @click.stop="showModal('修改用户信息', CURDTYPE.修改, record as TableRowFeilds)">编辑</a-button>
                <a-popconfirm title="确定删除?" @confirm="onDelete(record as TableRowFeilds)">
                  <a-button danger size="small">删除</a-button>
                </a-popconfirm>
                <a-button type="primary" size="small" @click.stop="showModal('修改密码', CURDTYPE.修改密码, record as TableRowFeilds)">修改密码</a-button>
              </a-space>
            </template>
          </template>
        </a-table>
      </div>
    </section>
    <a-modal v-model:open="open" :width="900" :title="modalTitle" :maskClosable="false" centered destroyOnClose>
      <template #footer>
        <a-button key="back" @click="handleClose">关闭</a-button>
        <a-button key="submit" type="primary" v-if="crudType !== CURDTYPE.查看" :loading="confirmLoading" @click="handleOk">确定</a-button>
        <a-button key="reset" @click="resetFormState" v-if="crudType !== CURDTYPE.查看">重置</a-button>
      </template>
      <section class="modal-content-box">
        <a-form ref="formRef" :model="formState" :rules="rules" :label-col="labelCol" :wrapper-col="wrapperCol">
          <a-form-item label="用户名" name="username" v-if="crudType !== CURDTYPE.修改密码">
            <a-input
              v-model:value="formState.username"
              placeholder="用户名"
              :disabled="disabledFormItem || crudType == CURDTYPE.修改"
              :maxlength="50"
              show-count
              autocomplete="off"
            />
          </a-form-item>
          <a-form-item label="密码" name="password" v-if="[CURDTYPE.新增, CURDTYPE.修改密码].includes(crudType)">
            <a-input-password v-model:value="formState.password" placeholder="用户密码" :disabled="disabledFormItem" :maxlength="50" show-count autocomplete="off" />
          </a-form-item>
          <a-form-item label="确认密码" name="checkPassword" v-if="[CURDTYPE.修改密码].includes(crudType)">
            <a-input-password v-model:value="formState.checkPassword" placeholder="确认密码" :maxlength="50" show-count autocomplete="off" />
          </a-form-item>
          <a-form-item label="用户昵称" name="nickname" v-if="crudType !== CURDTYPE.修改密码">
            <a-input v-model:value="formState.nickname" placeholder="用户昵称" :disabled="disabledFormItem" :maxlength="255" show-count autocomplete="off" />
          </a-form-item>
          <a-form-item label="性别" name="gender" v-if="crudType !== CURDTYPE.修改密码">
            <a-radio-group v-model:value="formState.gender" :disabled="disabledFormItem">
              <a-radio :value="UserGender.男">{{ UserGender[1] }}</a-radio>
              <a-radio :value="UserGender.女">{{ UserGender[0] }}</a-radio>
              <a-radio :value="UserGender.未知">{{ UserGender[-1] }}</a-radio>
            </a-radio-group>
          </a-form-item>
          <a-form-item label="手机号" name="phone" v-if="crudType !== CURDTYPE.修改密码">
            <a-input v-model:value="formState.phone" placeholder="手机号" :disabled="disabledFormItem" :maxlength="18" show-count autocomplete="off" />
          </a-form-item>
          <a-form-item label="邮箱" name="email" v-if="crudType !== CURDTYPE.修改密码">
            <a-input v-model:value="formState.email" placeholder="邮箱" :disabled="disabledFormItem" :maxlength="255" show-count autocomplete="off" />
          </a-form-item>
          <a-form-item label="备注" name="remark" v-if="crudType !== CURDTYPE.修改密码">
            <a-textarea v-model:value="formState.remark" placeholder="备注" :disabled="disabledFormItem" :rows="4" :maxlength="255" show-count autocomplete="off" />
          </a-form-item>
          <a-form-item label="头像" name="upload" extra="支持png、jpeg格式图片" v-if="crudType !== CURDTYPE.修改密码">
            <UploadFile v-model:file-list="fileList" accept=".png,.jpeg" :maxCount="1" :show-upload-list="true" :disabled="disabledFormItem" @success="uplaodSuccess" />
          </a-form-item>
        </a-form>
      </section>
    </a-modal>
  </section>
</template>

<script setup lang="ts">
import { UserService } from '@/api'
import type { TableColumnsType, TableProps } from 'ant-design-vue'
import type { Rule } from 'ant-design-vue/es/form'
import { FormState, Pagination, SearchForm, TableRowFeilds, UserGender } from './types'
defineOptions({ name: 'User' })
enum CURDTYPE {
  新增 = 1,
  修改 = 2,
  查看 = 3,
  删除 = 4,
  修改密码 = 5,
}
// 分页器配置
const pageSet = ref<Pagination>({
  current: 1,
  pageSize: 10,
  total: 0,
  pageSizeOptions: ['10', '20', '30', '50', '100'],
  showQuickJumper: true,
  showTotal: (total: number) => {
    return `总数：${total} 条`
  },
})

// 搜素表单
const searchRormRef = ref()
const searchFormState = reactive<SearchForm>({
  username: '',
  phone: '',
  gender: null,
})
function onFinishSearch(values: SearchForm): void {
  console.log('Search-Params:', values)
  pageSet.value.current = 1
  getListData()
}
// 重置搜索表单
function resetSearchForm(): void {
  searchFormState.gender = null
  searchRormRef.value.resetFields()
  getListData()
}
const disabledSeachBtn = computed(() => {
  return !(searchFormState.username || searchFormState.phone)
})

const mainContentRef = ref<HTMLElement>()
const tableHeight = ref<number>(500)
const columns: TableColumnsType = [
  { title: '序号', width: 80, dataIndex: 'index', key: 'index', fixed: 'left', align: 'center' },
  { title: '用户名', minWidth: 150, dataIndex: 'username', key: 'username', fixed: 'left', align: 'center' },
  { title: '用户昵称', dataIndex: 'nickname', key: 'nickname', minWidth: 150, align: 'center' },
  {
    title: '性别',
    dataIndex: 'gender',
    key: 'gender',
    minWidth: 150,
    align: 'center',
    filterMultiple: false,
    filters: [
      { text: UserGender[1], value: UserGender.男 },
      { text: UserGender[0], value: UserGender.女 },
      { text: UserGender[-1], value: UserGender.未知 },
    ],
  },
  { title: '手机号', dataIndex: 'phone', key: 'phone', minWidth: 150, align: 'center' },
  { title: '邮箱', dataIndex: 'email', key: 'email', minWidth: 150, align: 'center' },
  {
    title: '操作',
    key: 'operation',
    fixed: 'right',
    align: 'center',
    width: 280,
  },
]
const tableLoading = ref<boolean>(false)
const tableData = ref<TableRowFeilds[]>([])

function handleTableChange(pag: { pageSize: number; current: number }, filters: any, sorter: any): TableProps['onChange'] {
  console.log('pag:==>', pag)
  console.log('filters:==>', filters)
  console.log('sorter:==>', sorter)
  searchFormState.gender = filters.gender ? filters.gender[0] : null
  pageSet.value = Object.assign(pageSet.value, pag)
  getListData()
  return
}

/** 新增、修改、查看、删除相关功能 */
const crudType = ref<number>(1)
const disabledFormItem = computed(() => {
  return crudType.value === CURDTYPE.查看
})
const formRef = ref()
const labelCol = { span: 5 }
const wrapperCol = { span: 17 }
const formState = ref<FormState>({
  username: '',
  password: '',
  nickname: '',
  gender: -1,
  phone: '',
  remark: '',
  email: '',
  avatar: '',
})
const validateUsername = async (_rule: Rule, value: string) => {
  const reg = /^[a-zA-Z0-9#$%_-]+$/
  if (value === '') {
    return Promise.reject('请输入用户名！')
  } else if (value.length < 4) {
    return Promise.reject('长度至少为4位！')
  } else if (value.length > 18) {
    return Promise.reject('长度最长为18位！')
  } else if (!reg.test(value)) {
    return Promise.reject('用户名只能是由字母、数字或者 #、$、%、_、- 这些字符组合')
  } else {
    return Promise.resolve()
  }
}
const validatePass = async (_rule: Rule, value: string) => {
  const reg = /^[a-zA-Z0-9@#$%_-]+$/
  if (value === '') {
    return Promise.reject('请输入密码！')
  } else if (value.length < 6) {
    return Promise.reject('密码长度至少为6位！')
  } else if (value.length > 18) {
    return Promise.reject('密码长度最长为18位！')
  } else {
    if (formState.value.checkPassword !== '') {
      formRef.value.validateFields('checkPassword')
    }
    return Promise.resolve()
  }
}
const validatePass2 = async (_rule: Rule, value: string) => {
  if (value === '') {
    return Promise.reject('请再次输入密码！')
  } else if (value !== formState.value.password) {
    return Promise.reject('两次输入输入密码不匹配！')
  } else {
    return Promise.resolve()
  }
}
const rules: Record<string, Rule[]> = {
  username: [{ required: true, validator: validateUsername, trigger: 'change' }],
  password: [{ required: true, validator: validatePass, trigger: 'change' }],
  checkPassword: [{ required: true, validator: validatePass2, trigger: 'change' }],
}
function resetFormState(): void {
  formRef.value.resetFields()
  pageSet.value.current = 1
  getListData()
}
const modalTitle = ref<string>('')
const open = ref<boolean>(false)
const confirmLoading = ref<boolean>(false)
// 打开弹窗
function showModal(title: string, type: CURDTYPE, row?: TableRowFeilds): void {
  modalTitle.value = title
  crudType.value = type
  console.log('showModal row:==>', row)
  formState.value = {
    username: '',
    password: '',
    nickname: '',
    gender: -1,
    phone: '',
    remark: '',
    email: '',
    avatar: '',
  }
  if (type !== CURDTYPE.新增 && row) {
    Object.entries(row).forEach(([key, val]) => {
      /**@ts-ignore */
      formState.value[key] = val
    })
    if (fileList.value.length === 0) {
      fileList.value = [{ uid: 1, name: '头像', status: 'done', url: row.avatar, thumbUrl: row.avatar }]
    }
  }
  open.value = true
}

// 弹窗确定
function handleOk(): void {
  confirmLoading.value = true
  formRef.value
    .validate()
    .then(async () => {
      const data = toRaw(formState.value)
      console.log('values', data)
      let res = null
      if (crudType.value === CURDTYPE.新增) {
        res = await UserService.add(data)
      } else if (crudType.value === CURDTYPE.修改) {
        res = await UserService.update(data.id + '', data)
      } else if (crudType.value === CURDTYPE.修改密码) {
        res = await UserService.modifyPassword(data.id + '', { password: data.password, checkPassword: data.checkPassword + '' })
      }
      confirmLoading.value = false
      console.log('res:==>', res)
      if (res?.success) {
        window.$message.success(`${CURDTYPE[crudType.value]}成功！`)
        open.value = false
        getListData()
      } else {
        window.$message.error(`${CURDTYPE[crudType.value]}失败！` + res?.message)
      }
    })
    .catch((error: any) => {
      confirmLoading.value = false
      console.log('error', error)
    })
}

// 确定删除
async function onDelete(record: TableRowFeilds) {
  const row = toRaw(record)
  console.log('onDelete:==>', row)
  const res = await UserService.remove(row?.id)
  if (res?.success) {
    window.$message.success('删除用户成功！')
    getListData()
    return true
  } else {
    window.$message.error('删除用户失败！' + res?.message)
    return false
  }
}

// 弹窗关闭后的回调
function handleClose() {
  confirmLoading.value = false
  open.value = false
}

// 获取列表数据
async function getListData() {
  tableLoading.value = true
  const params: UserEntity.SearchParams = {
    page: pageSet.value.current,
    pageSize: pageSet.value.pageSize,
    username: searchFormState.username,
    phone: searchFormState.phone,
    gender: searchFormState.gender,
  }
  const res = await UserService.page(params)
  console.log('getList：==>', res)
  if (res?.success) {
    const list = res?.data?.list || []
    tableData.value = list
    pageSet.value.total = res?.data?.total || 0
  } else {
    tableData.value = []
  }
  tableLoading.value = false
}

const fileList = ref<any[]>([])

function uplaodSuccess(data: any) {
  formState.value.avatar = data?.url
  console.log('uplaodSuccess:==>', data, fileList.value)
}

onMounted(() => {
  if (mainContentRef.value) {
    tableHeight.value = mainContentRef.value.offsetHeight - 64
  }
  getListData()
})
</script>

<style lang="scss" scoped>
.main-box {
  width: 100%;
  height: calc(100% - 76px);
  margin-top: 12px;

  .main-content {
    width: 100%;
    height: calc(100% - 52px);
  }
}
.modal-content-box {
  padding-top: 24px;
  height: 700px;
  width: 100%;
  overflow: hidden auto;
}
</style>
